<?php
error_reporting(E_ALL);

require_once "DpPhpbb3.class.php";

define("VERTICAL_LAYOUT_INDEX", 1);
define("HORIZONTAL_LAYOUT_INDEX", 0);

// ID: $Id: $

/**
 * DpUser Class.
 *
 *
 */

class DpSessionUser extends DpUser
{
    public function __construct($sessionid) {
        global $dpdb;

        $sql = "SELECT u.username_clean AS username
                FROM phpbb3.phpbb_users u
                JOIN phpbb3.phpbb_sessions s
                    ON u.user_id = s.session_user_id
                WHERE s.session_id = '{$sessionid}'";
        $username = $dpdb->SqlOneValue($sql);
        if($username != "") {
            parent::__construct($username);
        }
    }
}

class DpUser
{
    protected $_username;
    protected $_bb;
    protected $_row;
    protected $_settings;
    protected $_permissions;
    protected $_profiles;
    /** @var $_profile DpUserProfile */
    protected $_profile;

    /**
     * Class Initializer
     *
     */

    public function __construct($username) {
        if($username) {
            $this->_username = $username;
        }
        else {
            $this->_bb = new DpPhpbb3();
            $this->_username = $this->_bb->UserName();
        }
    }

    // load prefs from user and active profile to $_row, 
    // settings to $_settings with FetchUserSettings,
    // prefs to $_prefs with RefreshProfile,
    // profiles to $_profiles with a sql query

    protected function init($username) {
        global $dpdb;

        $this->_username = $username;
        $this->RefreshProfile($username);

        $sql = "SELECT 
                    u.profilename,
                    u.username,
                    bb_id,
                    real_name,
                    postprocessor,
                    date_created,
                    u_privacy,
                    i_theme,
                    email_updates,
                    u_neigh,
                    i_pmdefault,
                    team_1,
                    team_2,
                    team_3,
                    u_id,
                    CASE WHEN ursa.id IS NULL
                        THEN 0 ELSE 1 END AS is_sa,
                    CASE WHEN urpm.id IS NULL
                        THEN 0 ELSE 1 END AS is_pm
                FROM users AS u
                LEFT JOIN user_roles ursa
                    ON u.username = ursa.username
                    AND ursa.rolename = 'sa'
                LEFT JOIN user_roles urpm
                    ON u.username = urpm.username
                    AND urpm.rolename = 'pm'
                WHERE u.username = '$username'";
        $this->_row = $dpdb->SqlOneRow($sql);
        
        if(empty($this->_row)) {
            $this->create_dp_user();
            $this->RefreshProfile($this->Username());
        }
        $this->_settings = $this->FetchUserSettings($username);
        $this->_permissions = $this->FetchUserPermissions($username);
        $this->_profiles = $dpdb->SqlRows("
            SELECT * FROM user_profiles
            WHERE username = '$username'");
    }

    protected function Profile() {
        if(! $this->_profile)
            $this->RefreshProfile();
        assert($this->_profile);
        return $this->_profile;
    }

    public function IsPPer() {
        return $this->_row['postprocessor'] != "";
    }

    public function IsPPVer() {
    }

//    public function PostNewProject($project) {
//        $id = $this->_bb->PostNewProject($project);
//        $project->SetForumPostId($id);
//        return $id;
//    }


    public function UploadPath() {
        return "/var/ftp-shared/uploads/dpftp/{$this->Username()}";
    }

    public function IsRegisteredOnForum() {
        return $this->_bb->IsRegistered();
    }

    public function IsAccessRequestReviewer() {
        return !empty($this->_settings['access_request_reviewer']);
    }

    public function IsSiteTranslator() {
        return !empty($this->_settings['site_translator']);
    }

    public function IsSiteNewsEditor() {
        return !empty($this->_settings['site_news_editor']);
    }

    public function LayoutIndex() {
        return $this->_profile->LayoutIndex();
    }

    public function ShowStatusBar() {
        return $this->_profile->ShowStatusBar();
    }

    public function IsVerticalLayout() {
        return $this->_profile->IsVerticalLayout();
    }

    public function VerticalTextChars() {
            return $this->_profile->VerticalTextChars();
    }
    public function HorizontalTextChars() {
            return $this->_profile->HorizontalTextChars();
    }
    public function TextChars() {
        return $this->_profile->TextChars();
    }

    public function VerticalZoom() {
            return $this->_profile->VerticalZoom();
    }

    public function HorizontalZoom() {
            return $this->_profile->HorizontalZoom();
    }

    public function Zoom() {
        return $this->_profile->Zoom();
    }

    public function SetZoom($zoom) {
//        global $dpdb;
        if($zoom < 25)
            $zoom = 25;
        if($zoom > 400)
            $zoom = 400;
        if($this->IsVerticalLayout())
            $this->set_active_profile_field("v_zoom", $zoom);
        else
            $this->set_active_profile_field("h_zoom", $zoom);
    }

    public function VerticalTextLines() {
            return $this->_profile->VerticalTextLines();
    }
    public function HorizontalTextLines() {
            return $this->_profile->HorizontalTextLines();
    }

    public function TextColumns() {
        return $this->TextChars();
    }

    public function ImagePct() {
        return 100 - $this->TextFramePct();
    }

    public function VerticalTextFramePct() {
            return $this->_profile->VerticalTextFramePct();
    }

    public function HorizontalTextFramePct() {
            return $this->_profile->HorizontalTextFramePct();
    }

    public function TextFramePct() {
        return $this->_profile->TextFramePct();
    }

//    public function TextCols() {
//        return $this->_profile->TextCols();
//    }

    public function TextLines() {
        return $this->_profile->TextLines();
    }

    public function VerticalWrap() {
            return $this->_profile->VerticalWrap();
    }

    public function HorizontalWrap() {
            return $this->_profile->HorizontalWrap();
    }


    public function TextWrap() {
        return $this->_profile->TextWrap();
    }

    public function IsVerticalTextScroll() {
            return $this->_profile->IsVerticalTextScroll();
    }

    public function IsHorizontalTextScroll() {
            return $this->_profile->IsHorizontalTextScroll();
    }

//    public function IsTextScroll() {
//        return $this->_profile->IsTextScroll();
//    }


    public function Uid() {
        return $this->_row['u_id'];
    }

    public function CreditName() {
        $credit_name = $this->Setting("credit_name");
        return ($credit_name
                    ? $credit_name
                    : ($this->Realname()
                        ? $this->Realname()
                        : $this->Username()));
    }

//    public function NameToActiveUser() {
//        global $User;
//        if($User->IsSiteManager())
//            return $this->RealName();
//
//        if($this->IsPublic())
//            return $this->RealName();
//        else
//            return "(anonymous)";
//    }
//
//    public function Privacy() {
//        return $this->_profile->Privacy();
//    }
//
//    public function IsPrivate() {
//        return $this->_profile->IsPrivate();
//    }
//
//    public function IsAnonymous() {
//        return $this->_profile->IsAnonymous();
//    }
//
//    public function IsPublic() {
//        return $this->_profile->IsPublic();
//    }

//    public function SafeNameString() {
//        // this should be using the phpbb safe username
//        return preg_replace( "/ /", "_",
//                            strtolower($this->Username()));
//    }

//    public function SafeName($role) {
//        $key = $role."_anonymous";
//        return $this->BooleanSetting($key)
//            ? ""
//            : $this->CreditName();
//    }

//    public function IsVisibleToActiveUser() {
//        global $User;
//
//        if($this->Username() == $User->UserName())
//            return true;
//
//        if($this->IsPrivate())
//            return false;
//
//        if($User->IsSiteManager())
//            return true;
//
//        if($this->IsPublic())
//            return true;
//
//        return ($this->IsAnonymous() && $User->IsLoggedIn());
//    }

    public function IsShowFilteredNumbers() {
        return $this->BooleanSetting("show_filtered_numbers");
    }

    public function SetShowFiteredNumbers($bval) {
        $this->SetBoolean("show_filtered_numbers", $bval);
    }

    public function SwitchLayout() {
        $this->set_active_profile_field("i_layout",
                    ($this->LayoutIndex() == 0 ? 1 : 0));
        $this->RefreshProfile();
    }

    public function IsToolbar() {
        return $this->_profile->IsToolbar();
    }

//    public function IsStatusBar() {
//        return $this->_profile->IsStatusBar();
//    }

//    public function InterfaceIndex() {
//        return $this->_profile->InterfaceIndex();
//    }

//    public function IsEnhancedLayout() {
//        return $this->InterfaceIndex() != 0;
//    }

    public function IsPMDefaultSearch() {
        return $this->PMDefault() == 2; 
    }

    public function IsPMDefaultAllProjects() {
        return $this->PMDefault() == 0; 
    }

    public function IsPMDefaultActiveProjects() {
        return $this->PMDefault() == 1; 
    }

    public function PMDefault() {
        return $this->_row['i_pmdefault'];
    }

    public function IsNeighbors() {
        return ($this->Neighbors() > 0);
    }

    public function Neighbors() {
        return $this->_profile->Neighbors();
    }

    /**
     * Set the Real Name of the User
     *
     */

    public function DateCreatedInt() {
        return $this->_row['date_created'];
    }   

    public function DateCreated() {
        return new DpDate($this->DateCreatedInt());
    }

    /**
     * Real Name of User
     */

    public function RealName() {
        return $this->_row['real_name'];
    }

    public function SetRealName($real_name) {
        $this->SetUserString("real_name", $real_name);
    }

    public function EmailAddress() {
        return $this->_bb->Email();
    }

//    public function UserPmProjects() {
//        global $dpdb;
//
//        $sql = "SELECT
//                    ismyprojects = 1,
//                    p.projectid,
//                    p.state,
//                    pt.taskcode,
//                        SUM(CASE
//                            WHEN pt.checkouttime IS NULL THEN 1
//                            ELSE 0 END)
//                            AS virgincount,
//                        SUM(CASE
//                            WHEN pt.checkouttime IS NOT NULL
//                                AND pt.completiontime IS NULL THEN 1
//                            ELSE 0 END)
//                            AS inprogresscount,
//                        SUM(CASE
//                            WHEN pt.completiontime IS NOT NULL THEN 1
//                            ELSE 0 END)
//                            AS completedcount,
//                        (
//                            SELECT COUNT(1) FROM pages
//                            WHERE projectid = pt.projectid
//                        ) AS pagecount
//                FROM projects AS p
//
//                JOIN pagetasks pt
//                    ON p.projectid = pt.projectid
//
//                WHERE
//                    p.username = '$username'
//                    AND p.state = 'A'
//                GROUP BY
//                    p.projectid,
//                    p.state,
//                    pt.taskcode";
//        $projs = $dpdb->SqlObjects($sql) ;
//        return $projs;
//    }

    /**
     * Returns the username provided at creation of User object
     */

    public function Username() {
        return $this->_row['username'];
    }

    public function Language() {
        return $this->_bb->Language();
    }

    /**
     * Return the number of days between the dates on
     * which two date values occurred, removing funny
     * stuff for earliness or lateness within day of each.
     */

    protected function _daysBetween($earlierdate, $laterdate) {
        return ($laterdate - $earlierdate) / 24 / 60 / 60 ;
    }

    public function IsQualifiedForRound($round) {
        switch($round) {
            default:
                return true;
        }
    }

    public function MyPages() {
        global $dpdb ;

        $sql = "SELECT DISTINCT
                    pt.projectid,
                    pt.pagecode,
                    pt.taskcode,
                    p.nameofwork,
                    t.sequencenumber,
                    1 AS pages,
                    1 AS diffcount,
                    1 AS pages_mine,
                    UNIX_TIMESTAMP() AS max_round_timestamp,
                    UNIX_TIMESTAMP() AS date_diffable
                FROM
                    pagetasks AS pt
                JOIN
                    projects AS p
                ON
                    pt.projectid = p.projectid
                JOIN
                    tasks AS t
                ON
                    pt.taskcode = t.taskcode
                WHERE
                    pt.username = '{$this->Username()}'";
        return $dpdb->SqlObjects($sql) ;
    }

    public function IsSiteManager() {
        return $this->_row['is_sa'] != 0;
    }

    public function IsProjectManager() {
        return $this->_row['is_pm'] != 0;
    }

    public function IsProjectFacilitator() {
        return false;
    }

    public function IsImageSourcesManager() {
        return "" != $this->_settings['image_sources_manager'];
    }

    public function IsHideSpecialColors() {
        return false;
    }

    public function PageCount() {
        global $dpdb;

        return $dpdb->SqlOneValue("
            SELECT COUNT(1) 
            FROM page_events AS pe
            LEFT JOIN page_events AS pe2
                ON pe.projectid = pe2.projectid
                AND pe.page_name = pe2.page_name
                AND pe.task_code = pe2.task_code
                AND pe.event_id < pe2.event_id
            WHERE pe.username = '{$this->Username()}'
                AND pe.event_type = 'save_done'
                AND pe2.event_id IS NULL
                ");
    }

    public function MayManageRoles() {
        return $this->IsSiteManager();
    }
    public function MayMenteeinRound($roundid) {
        switch($roundid) {
            default:
                return true;
        }
    }

    public function MayWorkInRound($roundid) {
        switch($roundid) {
            default:
                return true;
        }
    }

    public function MayDownloadProject() {
        return $this->MayWorkInRound("PP");
    }

//    public function IsPermission($code) {
//        return isset($this->_permissions);
//    }

    public function BooleanSetting($key) {
        return empty($this->_settings[$key])
            ? false
            : $this->_settings[$key] == "yes";
    }

    protected function get_setting($setting) {
        return empty($this->_settings[$setting])
            ? ""
            : $this->_settings[$setting] ;
    }

    public function Setting($val) {
        return $this->get_setting($val);
    }

    // A wrapper around set_value() for boolean values.
    public function SetBoolean($settingCode, $boolval) {
        $this->SetSetting($settingCode, ($boolval ? 'yes' : NULL) );
    }

    public function SetSetting($setting, $val) {
        global $dpdb;
        if(empty($val)) {
            $dpdb->SqlExecute("
                DELETE FROM usersettings
                WHERE username = '$this->_username'
                AND setting = '$setting'");            
            unset($this->_settings[$setting]);
        }
        else {
            $dpdb->SqlExecute("
                REPLACE INTO usersettings
                    (username, setting, value)
                VALUES
                    ('$this->_username', '$setting', '$val')");
            $this->_settings[$setting] = $val;
        }
    }

//    public function SaveSettings() {
//        global $dpdb;
//        foreach($this->_settings as $setting) {
//            $dpdb->SqlExecute("
//                REPLACE usersettings
//                    (username, setting, value)
//                VALUES
//                    ( $this->_username,
//                    $this->_settings['setting'],
//                    $this->_settings['value'])");
//        }
//    }

    public function ForumUserId() {
        return $this->_row['bb_id'];
    }

    public function FetchUserSettings($username = null) {
        global $dpdb;
        global $User;
        if(!$username)
            $username = $User->Username();

        $ary = array();
        $rows = $dpdb->SqlRows( "
            SELECT setting, value FROM usersettings
            WHERE username = '$username'");
        foreach($rows as $row) 
        {
            $ary[$row['setting']] = $row['value'];
        }
        return $ary;
    }

    public function FetchUserPermissions($username = null) {
        global $dpdb;
        global $User;
        if(!$username)
            $username = $User->Username();

        $ary = array();
        $rows = $dpdb->SqlRows( "
            SELECT permission_code FROM user_permissions
            WHERE username = '$username'");
        foreach($rows as $row) 
        {
            $ary[$row['permission_code']] = true;
        }
        return $ary;
    }

    public function SetCreditName($name) {
        $this->SetUserString("credit_name", $name);
    }

    public function SetUserString($fieldname, $value) {
        global $dpdb;
        $dpdb->SqlExecute( "
                UPDATE users SET $fieldname = '$value'
                WHERE username = '{$this->Username()}'");
    }

/*
    public function ProfileId() {
        return "NULL";
    }
*/

    public function DeleteProfile($profilename) {
        global $dpdb;
        global $User;

        $username = $User->Username();

        $dpdb->SqlExecute("
            DELETE FROM user_profiles
            WHERE username = '$username'
                AND profilename = '$profilename'");

        // if the deleted profile is current, set current to default
        $dpdb->SqlExecute("
             UPDATE users AS u
             SET profilename = 'default'
             WHERE u.username = '$username'
                AND u.profilename = '$profilename'");

        $this->RefreshProfile($this->Username());  // just in case
    }

    public function ProfileCount() {
        return count($this->_profiles);
    }

    public function SetProfile($profilename) {
        global $dpdb, $User;
        $username = $User->Username();

        $dpdb->SqlExecute("
            UPDATE users AS u
            -- join to make sure profilename exists for user
            JOIN user_profiles AS up
            ON u.username = up.username
                AND u.profilename = up.profilename
            SET u.profilename = '$profilename'
            WHERE u.username = '$username'");
    }


    public function UpdateProfile($args, $profilename) {
        global $User;
        global $dpdb;

        if(! $dpdb->SqlExists("
            SELECT 1 FROM user_profiles
            WHERE username = '{$User->Username()}'
                AND profilename = '$profilename'"))
        {
            $dpdb->SqlExecute("
                INSERT INTO user_profiles
                    (username, profilename)
                VALUES
                    ('{$this->Username()}', '$profilename')");
        }

        // $dpdb->SqlExecute("
        $sql = "
            UPDATE user_profiles
            SET
                i_res       = ".SqlInteger($args['i_res']) . ",
                i_layout    = ".SqlInteger($args['i_layout']) . ",
                i_newwin    = ".SqlInteger($args['i_newwin']) . ",
                i_toolbar   = ".SqlInteger($args['i_toolbar']) . ",
                i_statusbar = ".SqlInteger($args['i_statusbar']) . ",
                v_font_face = ".SqlQuote($args['v_font_face']).",
                v_font_size = ".SqlQuote($args['v_font_size']).",
                v_zoom      = ".SqlInteger($args['v_zoom']).",
                v_tframe    = ".SqlInteger($args['v_tframe']).",
                v_tscroll   = ".SqlInteger($args['v_tscroll']).",
                v_tlines    = ".SqlInteger($args['v_tlines']).",
                v_tchars    = ".SqlInteger($args['v_tchars']).",
                v_twrap     = ".SqlInteger($args['v_twrap']).",
                h_font_face = ".SqlQuote($args['h_font_face']).",
                h_font_size = ".SqlQuote($args['h_font_size']).",
                h_zoom      = ".SqlInteger($args['h_zoom']).",
                h_tframe    = ".SqlInteger($args['h_tframe']).",
                h_tscroll   = ".SqlInteger($args['h_tscroll']).",
                h_tlines    = ".SqlInteger($args[ 'h_tlines']).",
                h_tchars    = ".SqlInteger($args['h_tchars']).",
                h_twrap     = ".SqlInteger($args['h_twrap'])."
            WHERE 
                username = '{$User->Username()}'
                AND profilename = '$profilename'";
        // die(PrettySql($sql));
        $dpdb->SqlExecute($sql);
    }

    public function AddProfile($args, $profilename) {
        $this->UpdateProfile($args, $profilename);
    }

    public function RefreshProfile($username = null) {
        require_once "DpUserProfile.class.php";
        if(! $username)
            $username = $this->Username();
        $this->_profile = new DpUserProfile($username);
    }

    public function IsEmailUpdates() {
        return $this->_profile->IsEmailUpdates();
    }

    public function LastActivityTimeInt() {
        return $this->_profile->LastActivityTimeInt();
    }

    public function ActiveProfileName() {
        return $this->_profile->ProfileName();
    }

    public function VerticalFontFace() {
        return $this->_profile->VerticalFontFace();
    }

    public function HorizontalFontFace() {
        return $this->_profile->HorizontalFontFace();
    }

    public function FontFace() {
        return $this->_profile->FontFace();
    }

    public function VerticalFontSize() {
        return $this->_profile->VerticalFontSize();
    }

    public function HorizontalFontSize() {
        return $this->_profile->HorizontalFontSize();
    }

    public function FontSize() {
        return $this->_profile->FontSize();
    }

    private function set_active_profile_field($fieldname, $value) {
        global $dpdb;
        $sql = "
            UPDATE user_profiles
            SET $fieldname = '$value'
            WHERE username = '{$this->Username()}'
                AND profilename = '{$this->ActiveProfileName()}'";
        $dpdb->SqlExecute($sql);
        $this->RefreshProfile($this->Username());
    }

    public function SetFontFace($fontface) {
        $fld = ($this->IsVerticalLayout()
                    ? "v_font_face" : "h_font_face");
        $this->set_active_profile_field($fld, $fontface);
    }

    public function FontPointSize() {
        return $this->FontSize();
    }

    public function SetFontSize($size) {
        $fld = ($this->IsVerticalLayout()
                    ? "v_font_size" : "h_font_size");
        $this->set_active_profile_field( $fld, $size );
    }

    public function IsNewWindow() {
        return $this->_profile->IsNewWindow();
    }

    public function ScreenResolution() {
        return $this->_profile->ScreenResolution();
    }

    private function bbuser() {
        return $this->_bb->bb_user();
    }

//    public function PMUrl() {
//        global $Context;
//        return $Context->UrlForPMToUser($this->Username());
//    }

//    public function SetValue($key, $value) {
//        global $context;
//        $context->SetValue($key, $value);
//    }
    protected function create_dp_user() {
        global $dpdb;

        $username = $this->_bb->Username();
        $bbid     = $this->_bb->Uid();

        $dpdb->SqlExecute("
            INSERT INTO users (
                bb_id, username, date_created)
            VALUES (
            $bbid, '$username', UNIX_TIMESTAMP())");

        // add a default profile record with defaults from schema
        $dpdb->SqlExecute("
            INSERT INTO user_profiles
                (username, profilename)
            VALUES
                ('$username', 'default')");
    }
}

class DpThisUser extends DpUser
{

    function __construct($username = null, $password = null) {
        $this->_bb = new DpPhpbb3();

        if($this->_bb->IsLoggedIn()) {
            $username = $this->_bb->Username();
            $this->init($username);
            return;
        }

        // nothing from either session, try login
        if(! $username || ! $password) {
            return;
        }

        $this->_bb->DoLogin($username, $password);
        if($this->_bb->IsLoggedIn()) 
        {
            $username = $this->_bb->Username();
            assert(!empty($username));
            $this->init($username);
            return;
        }
    }

    public function LogOut() {
        if($this->_bb) {
            $this->_bb->DoLogout();
        }
        assert(! $this->IsLoggedIn());
    }

//    public function Params() {
//        return $this->_params;
//    }

    public function IsLoggedIn() {
        // return $this->_bb->IsLoggedIn();
        if($this->_bb->IsLoggedIn()) {
            assert($this->Username() != "");
            return true;
        }
        return false;
    }

    public function Team1() {
        return empty($this->_row['team_1'])
            ? 0
            : $this->_row['team_1'];
    }

    public function Team2() {
        return empty($this->_row['team_2'])
            ? 0
            : $this->_row['team_2'];
    }

    public function Team3() {
        return empty($this->_row['team_3'])
            ? 0
            : $this->_row['team_3'];
    }

    public function SetLatestVisit($projectid) {
    }

    public function InboxCount() {
        return $this->_bb->InboxCount();
    }

//    public function UserProfileFields($uaername) {
//        global $user;
//        return $user->get_profile_fields($username);
//    }


}
?>
